package a2_p04_ng_sw;


import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;



import org.jgrapht.alg.DijkstraShortestPath;
import org.jgrapht.graph.AbstractGraph;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.traverse.DepthFirstIterator;




public class AlgoDFS {
	
	
	
	
	private ArrayList<Object> theWay = new ArrayList<Object>();
	private ArrayList<String> theShortestWay = new ArrayList<String>();
	private int benoetigteKanten =0;
	private boolean isDefaultEgde = false;
	private boolean isString = false;

	public AlgoDFS(AbstractGraph<?, ?> graph, String start,String end){
		Iterator<?> iterEdge = graph.edgeSet().iterator();
		while(iterEdge.hasNext()){
			Object obj = iterEdge.next();
			if(obj instanceof DefaultEdge) {
				isDefaultEgde = true;
				break;
			}else break;
		}
		Iterator<?> isVertex = graph.vertexSet().iterator();
		while(isVertex.hasNext()){
			Object obj = isVertex.next();
			if(obj instanceof String) {
				isString = true;
				break;
			}else
				break;			
		}
		 if(isDefaultEgde && isString){
			out("String && DefaultEdge Ungewichtet ");
			AbstractGraph<String, DefaultEdge> tgraph = (AbstractGraph<String, DefaultEdge>)graph;
			findWayNormal(tgraph, start, end);
			
		 }else if(isString && !isDefaultEgde){
			 out("String & DefaultWeightedEdge Gewichet unattri");
			 AbstractGraph<String, DefaultWeightedEdge> tgraph = (AbstractGraph<String, DefaultWeightedEdge>)graph;
			 findWayGewichtet(tgraph, start, end);
			
		 }else{
			 out("Knoten & DefaultWeightedEdge Gewichet unattri");
			 AbstractGraph<Knoten, DefaultWeightedEdge> tgraph = (AbstractGraph<Knoten, DefaultWeightedEdge>)graph;
			 findWayGewichtetAttr(tgraph, start,end);
		 }		 
	}
	
	private void out(String str){
		System.out.println(str);
	}
	
//	public AlgoDFS(AbstractGraph<?, ?> graph, Knoten start,Knoten end){
////		out("Knoten & DefaultWeightedEdge gewichtet attri " + ecken);
//		 AbstractGraph<Knoten, DefaultWeightedEdge> tgraph = ( AbstractGraph<Knoten, DefaultWeightedEdge>) graph;
//		 this.graph=tgraph;	
//		 
//	}
	
	private Knoten getKnoten(AbstractGraph<Knoten, DefaultWeightedEdge> aGraph, String knotenName){
		Iterator<Knoten> iterVertex =  aGraph.vertexSet().iterator();
		while(iterVertex.hasNext()){
			Knoten a = iterVertex.next();
			if(a.getName().equals(knotenName)) return a;
		}
		return null;
	}

	
	private void findWayNormal(AbstractGraph<String, DefaultEdge> aGraph, String start, String end){
		
		DepthFirstIterator<String, DefaultEdge> bfsIter = new DepthFirstIterator<String, DefaultEdge>(aGraph, start);
		DijkstraShortestPath<String, DefaultEdge> dijIter = new DijkstraShortestPath<String, DefaultEdge>(aGraph,start,end);
		
		shortWay(bfsIter,dijIter);
	}
	
	private void findWayGewichtet(AbstractGraph<String, DefaultWeightedEdge> aGraph, String start, String end){
		
		DepthFirstIterator<String, DefaultWeightedEdge> bfsIter = new DepthFirstIterator<String, DefaultWeightedEdge>( aGraph, start);
		DijkstraShortestPath<String, DefaultWeightedEdge> dijIter = new DijkstraShortestPath<String, DefaultWeightedEdge>(aGraph,start,end);
		
		shortWay(bfsIter,dijIter);
	}
	private void findWayGewichtetAttr(AbstractGraph<Knoten, DefaultWeightedEdge> aGraph, String start,String end){
		Knoten s = getKnoten(aGraph, start);
		Knoten e = getKnoten(aGraph, end);
		DepthFirstIterator<Knoten, DefaultWeightedEdge> bfsIter = new DepthFirstIterator<Knoten, DefaultWeightedEdge>(aGraph, s);
		DijkstraShortestPath<Knoten, DefaultWeightedEdge> dijIter = new DijkstraShortestPath<Knoten, DefaultWeightedEdge>(aGraph,s,e);
		shortWay(bfsIter,dijIter);
	}
	
	private void shortWay(DepthFirstIterator<?, ?> bfsIter,DijkstraShortestPath<?, ?> dijIter){		
		
		
			while(bfsIter.hasNext()){
				Object tmp = bfsIter.next();
				
				theWay.add(tmp);
				
			}
			
		List hmm = new ArrayList();
		
		
		
		benoetigteKanten =(int) dijIter.getPathLength();
		hmm.addAll((Collection<?>)dijIter.getPathEdgeList());
		
		for(int i =0; i<hmm.size();i++){
			theShortestWay.add(hmm.get(i).toString());			
		}

	}

	
		
	public int getBenoetigteKanten(){
		return benoetigteKanten;
	}
	
	public ArrayList<String> getTheShortestWay(){
		return theShortestWay;
	}
	
	public ArrayList<Object> getTheWay(){
		return theWay;
	}
	
	
	
	
	
	
//	private static ArrayList<DefaultEdge> getNachbarnUngerichtet (AbstractGraph<String, DefaultEdge> graph,String node ){
//		return new ArrayList<DefaultEdge>(graph.edgesOf(node));
//		
//	}
//	
//	private static ArrayList<DefaultEdge> getNachbarnGerichtet (AbstractGraph<String, DefaultEdge> graph,String node){
//		
//		return  new ArrayList<DefaultEdge>(( (DirectedPseudograph<String, DefaultEdge>) graph).outgoingEdgesOf(node));
//		
//	}
//	
//	
//	private static ArrayList<String> getSourceAndTarget(DefaultEdge edge)
//	{
//		ArrayList<String> result = new ArrayList<String>();
//		
//		String temp = (edge.toString()).replace(" ", "").replace("(","").replace(")","");
//    	int separator = temp.indexOf(":");
//    
//    	result.add(temp.substring(0, separator));
//    	result.add(temp.substring(separator + 1));
//    	return result;
//   
//	}
//	
//	private static String getTarget(DefaultEdge edge)
//	{
//		return getSourceAndTarget(edge).get(1);
//	}
//	
//	private static String getSource(DefaultEdge edge)
//	{
//		return getSourceAndTarget(edge).get(0);
//	}

}
